using System;
using System.Linq;
using LinqRepositorySample.Domain;
using NHibernate.Linq;
using Rhinestone.Shared;

namespace LinqRepositorySample.Data.NHibernate
{
    public class NHibernateRepository<T> : RepositoryBase<T>
    {
        #region fields
        private IQueryable<T> _query;
        #endregion

        #region .ctor
        public NHibernateRepository()
        {
            if (UnitOfWork.Current == null)
                throw new ArgumentNullException();
            NHibernateUnitOfWork uow = UnitOfWork.Current as NHibernateUnitOfWork;
            if(uow == null)
                throw new ArgumentNullException();
            _query = uow.Session.Linq<T>();
        }
        #endregion

        #region Overrides of RepositoryBase<T>
        /// <summary>
        /// Gets the <see cref="IQueryable{T}"/> used by the <see cref="RepositoryBase{T}"/> 
        /// to execute Linq queries.
        /// </summary>
        /// <value>A <see cref="IQueryable{T}"/> instance.</value>
        /// <remarks>
        /// Inheritos of this base class should return a valid non-null <see cref="IQueryable{T}"/> instance.
        /// </remarks>
        protected override IQueryable<T> RepositoryQuery
        {
            get { return _query; }
        }

        /// <summary>
        /// Marks the entity instance to be saved to the store.
        /// </summary>
        /// <param name="entity">An instance of <typeparamref name="T"/> that should be saved
        /// to the database.</param>
        /// <remarks>Implementors of this method must handle both Insert and Update scenarios.</remarks>
        public override void Save(T entity)
        {
            if (entity == null)
                throw new ArgumentNullException();
            ((NHibernateUnitOfWork) UnitOfWork.Current).Session.SaveOrUpdate(entity);
        }

        /// <summary>
        /// Marks the entity instance to be deleted from the store.
        /// </summary>
        /// <param name="entity">An instance of <typeparamref name="T"/> that should be deleted.</param>
        public override void Delete(T entity)
        {
            if (entity == null)
                throw new ArgumentNullException();
            ((NHibernateUnitOfWork)UnitOfWork.Current).Session.Delete(entity);
        }
        #endregion
    }
}